package ld.oauth.blog.service.article.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ld.oauth.blog.mapper.article.ArticleMapper;
import ld.oauth.blog.model.bo.ArticleBo;
import ld.oauth.blog.model.bo.CommentBo;
import ld.oauth.blog.model.po.article.Article;
import ld.oauth.blog.model.po.article.ArticleCategory;
import ld.oauth.blog.model.po.article.ArticleLabel;
import ld.oauth.blog.model.po.article.Comment;
import ld.oauth.blog.model.qo.ArticleQo;
import ld.oauth.blog.model.vo.*;
import ld.oauth.blog.service.article.ArticleCategoryService;
import ld.oauth.blog.service.article.ArticleLabelService;
import ld.oauth.blog.service.article.ArticleService;
import ld.oauth.blog.service.article.CommentService;
import ld.oauth.blog.utils.PageResult;
import ld.oauth.blog.utils.PageUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.SetUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ld
 * @since 2022-09-24
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Autowired
    private ArticleCategoryService articleCategoryService;

    @Autowired
    private ArticleLabelService articleLabelService;

    @Autowired
    private CommentService commentService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveOrUpdate(ArticleBo articleBo) {
        Article article = new Article();
        BeanUtils.copyProperties(articleBo, article);
        saveOrUpdate(article);
        //绑定的文章分类和标签
        List<List<Integer>> list = articleBo.getLabelIds();
        Set<Integer> categoryList = SetUtils.newIdentityHashSet();
        Set<Integer> labeIdList = SetUtils.newIdentityHashSet();
        if (!CollectionUtils.isEmpty(list)) {
            list.stream().forEach(listChild -> {
                categoryList.add(listChild.get(0));//文章分类id
                labeIdList.add(listChild.get(1));//标签id
            });
            //文章绑定分类和标签
            articleBindCategoryAndLabel(article, categoryList, labeIdList);
        }
        return article.getId();
    }

    /**
     * 文章绑定分类和标签
     *
     * @param article
     * @param categoryList
     * @param labeIdList
     */
    public void articleBindCategoryAndLabel(Article article, Set<Integer> categoryList, Set<Integer> labeIdList) {
        //先删除 再绑定
        articleCategoryService.removeCategoryIdsByArticleId(article.getId());
        List<ArticleCategory> articleCategoryList = new ArrayList<>();
        categoryList.stream().forEach(categoryId -> {
            ArticleCategory articleCategory = new ArticleCategory();
            articleCategory.setArticleId(article.getId());
            articleCategory.setCategoryId(categoryId);
            articleCategoryList.add(articleCategory);
        });
        articleCategoryService.saveBatch(articleCategoryList);
        //先删除 再绑定
        articleCategoryService.removeLabelsIdsByArticleId(article.getId());
        List<ArticleLabel> articleLabelList = new ArrayList<>();
        labeIdList.stream().forEach(labelId -> {
            ArticleLabel articleLabel = new ArticleLabel();
            articleLabel.setArticleId(article.getId());
            articleLabel.setLabelId(labelId);
            articleLabelList.add(articleLabel);
        });
        articleLabelService.saveBatch(articleLabelList);
    }

    @Override
    public PageResult<ArticleVo> pageQuery(ArticleQo articleQo) {
        IPage<ArticleVo> articleVoIPage = PageUtil.createIPage(articleQo);
        if (articleQo != null) {
            if (articleQo.getCategoryId() != null && articleQo.getCategoryId() == 0) {
                articleQo.setCategoryId(null);
            }
        }
        PageResult<ArticleVo> pageResult = this.baseMapper.pageQuery(articleQo, articleVoIPage);

        return pageResult;
    }

    @Override
    public ArticleDetail articleDetailById(Integer id) {
        Article article = this.getBaseMapper().selectById(id);
        ArticleDetail articleDetail = new ArticleDetail();
        BeanUtils.copyProperties(article, articleDetail);
        List<LabelVo> labelVoList = this.getBaseMapper().selectLabelVoListByArticleId(id);
        List<List<Integer>> labelIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(labelVoList)) {
            labelVoList.stream().forEach(labelVo -> {
                if(!Objects.isNull(labelVo)){
                    List<Integer> list = new ArrayList<>();
                    list.add(labelVo.getCategoryId());
                    list.add(labelVo.getId());
                    labelIds.add(list);
                }
            });
            articleDetail.setLabelIds(labelIds);
        }
        return articleDetail;
    }

    /**
     * 更新文章浏览数
     *
     * @param id
     */
    @Override
    public void updateArticleViewCountById(Integer id) {
        Article article = this.baseMapper.selectById(id);
        article.setViewCount((article.getViewCount() + 1));
        this.baseMapper.updateById(article);
    }

    /**
     * 更新文章点赞数
     *
     * @param articleId
     * @param count
     */
    @Override
    public void updateArticleThumbById(Integer articleId, Integer count) {
        Article article = this.baseMapper.selectById(articleId);
        article.setThumhup((article.getThumhup() + count));
        this.baseMapper.updateById(article);
    }

    /**
     * 根据文章id获取评论list
     *
     * @param articleId
     */
    @Override
    public List<CommentVo> commentListByArticleId(Integer articleId) {
        List<CommentVo> commentVoList = this.baseMapper.commentListByArticleIdOrParentId(articleId,-1);
        //递归查询是否有子评论
        handleCommentChildList(articleId,commentVoList);
        return commentVoList;
    }

    /**
     * 递归查询是否有子评论
     * @param articleId
     * @param commentVoList
     */
    public void handleCommentChildList(Integer articleId,List<CommentVo> commentVoList){
        if(CollectionUtils.isNotEmpty(commentVoList)){
            commentVoList.stream().forEach(comment->{
                List<CommentVo> childList = this.baseMapper.commentListByArticleIdOrParentId(articleId, comment.getId());
                comment.setChildren(childList);
                handleCommentChildList(articleId,childList);
            });
        }else {
            return;
        }
    }

    /**
     * 新增文章评论
     * @param commentBo
     * @return
     */
    @Override
    public Boolean insertComment(CommentBo commentBo) {
        Comment comment = new Comment();
        BeanUtils.copyProperties(commentBo,comment);
        return commentService.saveOrUpdate(comment);
    }


    /**
     * 根据标签id分页查询文章列表
     * @param articleQo
     * @return
     */
    @Override
    public PageResult<ArticleDetail> queryArticleDetailByLabelId(ArticleQo articleQo) {
        IPage<ArticleDetail> iPage = PageUtil.createIPage(articleQo);
        PageResult<ArticleDetail> articleDetailPageResult = this.baseMapper.queryArticleDetailByLabelId(articleQo, iPage);
        return articleDetailPageResult;
    }
}
